﻿namespace NorthernLights.Controls
{
    using System;
    using System.Collections.ObjectModel;
    using System.Linq;
    using System.Windows;
    using Microsoft.Phone.Tasks;
    using NorthernLights;
    using NorthernLights.Controls.Tools;

    /// <summary>
    /// NagForReview class.
    /// </summary>
    public static class NagForReview
    {
        #region Fields
        #endregion

        #region Enums
        /// <summary>
        /// NagType items.
        /// </summary>
        [Flags]
        public enum NagType
        {
            /// <summary>
            /// Don't nag. Just record 'visits'.
            /// </summary>
            Never = 0,
    
            /// <summary>
            /// Show nag screen after X times
            /// </summary>
            AfterXTimes = 1,

            /// <summary>
            /// Show nag screen after X days.
            /// </summary>
            AfterXDays = 2,
        }
        #endregion

        #region Public Properties
        #endregion

        #region Public methods
        /// <summary>
        /// Check if to display nag screen.
        /// </summary>
        /// <param name="type">The desired NagType.</param>
        /// <param name="afterxdays">After x Days to show nag screen (-1 for never)</param>
        /// <param name="afterxtimes">After x Times to show nag screen (-1 for never)</param>
        public static void Check(NagType type, int afterxdays, int afterxtimes)
        {
            string title = "Thank you for your support!";
            string text = "Would you mind taking a minute and write a review?";
            string remind = "Ask me again later";

            Check(title, text, remind, type, afterxdays, afterxtimes);
        }

        /// <summary>
        /// Check if to display nag screen.
        /// </summary>
        /// <param name="title">The title for the popup.</param>
        /// <param name="text">The text for the poup.</param>
        /// <param name="remind">The text for the 'remind' part of the popup.</param>
        /// <param name="type">The desired NagType.</param>
        /// <param name="afterxdays">After x Days to show nag screen (-1 for never)</param>
        /// <param name="afterxtimes">After x Times to show nag screen (-1 for never)</param>
        public static void Check(string title, string text, string remind, NagType type, int afterxdays, int afterxtimes)
        {
            Check(title, text, remind, "review", "not now", type, afterxdays, afterxtimes);
        }

        /// <summary>
        /// Check if to display nag screen.
        /// </summary>
        /// <param name="title">The text to display as Title.</param>
        /// <param name="text">The main text to display.</param>
        /// <param name="remind">The text to display as reminder.</param>
        /// <param name="review">The text for the review button.</param>
        /// <param name="notnow">The text for the notnow button.</param>
        /// <param name="type">The desired NagType.</param>
        /// <param name="afterxdays">After x Days to show nag screen (-1 for never)</param>
        /// <param name="afterxtimes">After x Times to show nag screen (-1 for never)</param>
        public static void Check(string title, string text, string remind, string review, string notnow, NagType type, int afterxdays, int afterxtimes)
        {
            // check if user already reviewed app.
            if (PersistentVariables.Get<bool>(Enums.Variables.NagForReview_Reviewed.ToString()) == true)
            {
                return;
            }

            if (type == NagType.Never)
            {
                return;
            }

            // check nagtype
            Collection<string> data = PersistentVariables.Get<Collection<string>>(Enums.Variables.NagForReview_Data.ToString());

            if (data != null)
            {
            }
            else
            {
                data = new Collection<string>();
            }

            data.Add(DateTime.Now.ToString());

            bool show = false;

            if ((type & NagType.AfterXDays) == NagType.AfterXDays)
            {
                if (!show && afterxdays != -1)
                {
                    show = ShowAfterXDays(data, afterxdays);
                }
            }

            if ((type & NagType.AfterXTimes) == NagType.AfterXTimes)
            {
                if (!show && afterxtimes != -1)
                {
                    show = ShowAfterXTimes(data, afterxtimes);
                }
            }

            PersistentVariables.Set<Collection<string>>(Enums.Variables.NagForReview_Data.ToString(), data);

            // show
            if (show)
            {
                // reset data.
                data.Clear();
                PersistentVariables.Set<Collection<string>>(Enums.Variables.NagForReview_Data.ToString(), data);

                Deployment.Current.Dispatcher.BeginInvoke(() =>
                {
                    NotificationTool.ShowAgain(
                        title,
                        text,
                        remind,
                        false,
                        (value) =>
                            {
                                value = !value;

                                // if false, disable popup.
                                if (!value)
                                {
                                    PersistentVariables.Set<bool>(Enums.Variables.NagForReview_Reviewed.ToString(), true);
                                }
                            },
                        "popupreview",
                        new NotificationAction(
                            review, 
                            () =>
                                {
                                    PersistentVariables.Set<bool>(Enums.Variables.NagForReview_Reviewed.ToString(), true);
                                    var task = new MarketplaceReviewTask();
                                    task.Show();
                                }),
                        new NotificationAction(
                            notnow, 
                            () =>
                                {
                                    // do nothing.
                                }));
                });
            }
        }
        #endregion

        #region Private methods
        private static bool ShowAfterXTimes(Collection<string> items, int threshold)
        {
            if (items != null)
            {
                if (items.Count >= threshold)
                {
                    return true;
                }
            }

            return false;
        }

        private static bool ShowAfterXDays(Collection<string> items, int threshold)
        {
            if (items != null)
            {
                string firstItem = items.First<string>();
                
                if (!string.IsNullOrEmpty(firstItem))
                {
                    DateTime firstDate;

                    if (DateTime.TryParse(firstItem, out firstDate))
                    {
                        TimeSpan difference = DateTime.Now - firstDate;

                        if (difference.Days >= threshold)
                        {
                            return true;
                        }
                    }
                }
            }

            return false;
        }
        #endregion
    }
}
